<script lang="ts">
export default {
  name: "xt-dynamic-form",
};
</script>

<script setup lang="ts">
import xtForm from "../../../components/xt-form/src/main.vue";
import xtFormItem from "../../../components/xt-form-item/src/main.vue";
import xtRow from "../../../components/xt-row/src/main.vue";
import xtCol from "../../../components/xt-col/src/main.vue";
import xtInput from "../../../components/xt-input/src/main.vue";
import xtSelect from "../../../components/xt-select/src/main.vue";
import xtCheckbox from "../../../components/xt-checkbox/src/main.vue";
import xtRadio from "../../../components/xt-radio/src/main.vue";
import xtDatePicker from "../../../components/xt-date-picker/src/main.vue";
import xtCascader from "../../../components/xt-cascader/src/main.vue";
import Typings from "../../../typings";
import { computed, ref } from "vue";

interface Props {
  labelWidth?: number | string;
  data: Typings.Common.plainObj;
  formJson: Typings.DynamicForm.JsonType[];
}

const props = withDefaults(defineProps<Props>(), {
  labelWidth: 108,
  data: () => ({}),
  formJson: () => [],
});

const getFormJson = computed(() => {
  return props.formJson.filter((json) => !(json.isHide && json.isHide()));
});

const formIns = ref();
const getInstance = computed(() => formIns.value.instance);

defineExpose({
  instance: getInstance,
});
</script>

<template>
  <xt-form
    ref="formIns"
    class="xt-dynamic-form"
    :labelWidth="labelWidth"
    :model="data"
  >
    <xt-row :gutter="24">
      <xt-col
        :span="span || 12"
        :key="prop"
        v-for="{
          el,
          span,
          prop,
          label,
          rules,
          options = [],
          on = {},
          ...col
        } in getFormJson"
      >
        <xt-form-item :label="label" :prop="prop" :rules="rules">
          <template v-if="['input'].includes(el)">
            <xt-input
              v-model="data[prop]"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-input>
          </template>

          <template v-if="['textarea'].includes(el)">
            <xt-input
              type="textarea"
              v-model="data[prop]"
              v-bind="{ autosize: { minRows: 6 }, ...col }"
              v-on="on"
            ></xt-input>
          </template>

          <template v-if="['select'].includes(el)">
            <xt-select
              v-model="data[prop]"
              :options="options"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-select>
          </template>

          <template v-if="['checkbox'].includes(el)">
            <xt-checkbox
              v-model="data[prop]"
              :options="options"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-checkbox>
          </template>

          <template v-if="['radio'].includes(el)">
            <xt-radio
              v-model="data[prop]"
              :options="options"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-radio>
          </template>

          <template v-if="['cascader'].includes(el)">
            <xt-cascader
              v-model="data[prop]"
              :options="options"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-cascader>
          </template>

          <template v-if="['date-picker'].includes(el)">
            <xt-date-picker
              v-model="data[prop]"
              v-bind="{ ...col }"
              v-on="on"
            ></xt-date-picker>
          </template>

          <template v-if="['slot'].includes(el)">
            <slot :name="prop"></slot>
          </template>
        </xt-form-item>
      </xt-col>
    </xt-row>
  </xt-form>
</template>

<style lang="scss">
@use "../../../scss/xt-dynamic-form.scss";
</style>
